home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / mail / amitcp_ups10.lha / amiga / s_socket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-03  |  10.4 KB  |  650 lines

  1. #ifndef NOIDENT
  2. const static char RCSid[] = "$Header: qc:c-src/common/misclib/rcs/s_socket.c,v 1.6 1993/10/03 17:48:42 alph Exp $";
  3. #endif
  4.  
  5. /*
  6.  *----------------------------------------------------------------------
  7.  *
  8.  * $Source: qc:c-src/common/misclib/rcs/s_socket.c,v $
  9.  * $Revision: 1.6 $
  10.  * $Date: 1993/10/03 17:48:42 $
  11.  * $State: Exp $
  12.  * $Author: alph $
  13.  * $Locker:  $
  14.  *
  15.  *----------------------------------------------------------------------
  16.  *
  17.  * alph 
  18.  * 
  19.  * This code is (C) Copyright 1993 by Carsten Heyl. All rights reserved.
  20.  * This code is NOT in the Public Domain.
  21.  * It may be copied, modified or distributed as long as this notice is
  22.  * present.
  23.  *
  24.  *----------------------------------------------------------------------
  25.  * $Log: s_socket.c,v $
  26.  * Revision 1.6  1993/10/03  17:48:42  alph
  27.  * *** empty log message ***
  28.  *
  29.  * Revision 1.5  1993/10/03  16:36:54  alph
  30.  * corrected sendto parameter
  31.  *
  32.  * Revision 1.4  1993/10/02  19:34:00  alph
  33.  * added s_sendto
  34.  *
  35.  * Revision 1.3  1993/10/02  19:10:09  alph
  36.  * added header
  37.  *
  38.  *----------------------------------------------------------------------
  39.  */
  40.  
  41.  
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <fcntl.h>
  46.  
  47. #include <errno.h>
  48.  
  49. #include <sys/types.h>
  50. #include <netinet/in.h>
  51.  
  52. #ifdef __SASC
  53. #if 0
  54. #include <clib/socket_protos.h>
  55. #endif
  56. #include <pragmas/socket_pragmas.h>
  57. #include <proto/socket.h>
  58. #endif
  59.  
  60. #define PRIVATE_SOCKET_H
  61. #include "s_socket.h"
  62.  
  63. #define MAXFH S_MAXFH
  64.  
  65. /* FIXME: set atexit-handler for sockets too */
  66.  
  67. /* extern int SocketBase; */
  68.  
  69. static FILEEXT *files;
  70.  
  71. static void *zmalloc(size_t l)
  72. {
  73.     unsigned char *p = malloc(l);
  74.  
  75.     if(p)
  76.     memset(p, 0x00, l);
  77.  
  78.     return p;
  79. }
  80.  
  81. #define BUFSIZE 512
  82.  
  83. /*
  84.  does a FILE exists, which references fd ?
  85.  */
  86.  
  87. static int fd_has_refs(FILE *as, int fd)
  88. {
  89.     while(as)
  90.     {
  91.     if(fileno(as) == fd)
  92.         return 1;
  93.     as = as->_next;
  94.     }
  95.     return 0;
  96. }
  97.  
  98. static void s_fcloseall(void)
  99. {
  100.     while(files)
  101.     s_fclose(files);
  102. }
  103.  
  104. FILE *s_fdopen(int fd, const char *mode)
  105. {
  106.     FILEEXT *af;
  107.     unsigned char *buf;
  108.  
  109.     if(fd < MAXFH)
  110.     return fdopen(fd,mode);
  111.     else
  112.     {
  113.     af = zmalloc(sizeof(FILEEXT));
  114.     if(!af)
  115.         return NULL;
  116.     buf = zmalloc(BUFSIZE);
  117.     if(!buf)
  118.     {
  119.         free(af);
  120.         return NULL;
  121.     }
  122.     if(!strcmp(mode,"r"))
  123.     {
  124.         af->_flag = _IOREAD | _IOMYBUF;
  125.     }
  126.     else if(!strcmp(mode,"w"))
  127.     {
  128.         af->_flag = _IOWRT | _IOMYBUF;
  129.     }
  130.     else
  131.     {
  132.         fprintf(stderr,"s_fdopen: mode \"%s\" not supported\n", mode);
  133.  
  134.         free(af);
  135.         free(buf);
  136.         return 0;
  137.     }
  138.     
  139.     if(!files)
  140.         atexit(s_fcloseall);
  141.  
  142.     af->_next = files;
  143.     af->_ptr = buf;
  144.     af->_base = buf;
  145.     af->_size = BUFSIZE;
  146.     af->_flag |= _IOSOCK;
  147.     af->_file = fd;
  148.     files = af;
  149.  
  150.     return af;
  151.     }
  152. }
  153.  
  154. void s_fclose(FILE *af)
  155. {
  156.     FILE *pf = NULL, *sf = files;
  157.  
  158.     if(af->_file == 1)
  159.     {
  160.     fprintf(stderr,"s_fclose: someone tries to close stdout ;-(\n");
  161.     }
  162.  
  163.     if(!(af->_flag & _IOSOCK))
  164.     {
  165.     fclose(af);
  166.     }
  167.     else
  168.     {
  169.     if(af->_flag & _IOWRT)
  170.         s_fflush(af);
  171.  
  172.     while(sf && sf != af)
  173.     {
  174.         pf = sf;
  175.         sf = sf->_next;
  176.     }
  177.     if(sf)
  178.     {
  179.         if(pf)
  180.         pf->_next = sf->_next;
  181.         else
  182.         files = sf->_next;
  183. #if 1
  184.         if(! fd_has_refs(files, fileno(sf)))
  185.         s_close(fileno(sf)); /* FIXME: is this correct ? */
  186. #endif
  187.         free(sf->_base);
  188.         free(sf);
  189.     }
  190.     else
  191.     {
  192.         fprintf(stderr,"s_flose: illegal argument !!\n");
  193.     }
  194.     }
  195. }
  196.  
  197. size_t s_fread(void *b, size_t bsize, size_t n, FILE *fp)
  198. {
  199.     if(!(fp->_flag & _IOSOCK))
  200.     {
  201.     return fread(b, bsize, n, fp);
  202.     }
  203.     else
  204.     {
  205.     fprintf(stderr,"s_fread: not supported for sockets\n");
  206.     exit(20);
  207.     }
  208. }
  209. size_t s_fwrite(void *b, size_t bsize, size_t n, FILE *fp)
  210. {
  211.     if(!(fp->_flag & _IOSOCK))
  212.     {
  213.     return fwrite(b, bsize, n, fp);
  214.     }
  215.     else
  216.     {
  217.     fprintf(stderr,"s_ffwrite: not supported for sockets\n");
  218.     exit(20);
  219.     }
  220. }
  221.  
  222. static __inline int _s_fgetc(FILE *af)
  223. {
  224.     int n;
  225.  
  226.     if(af->_flag & _IOEOF)
  227.     {
  228.     return EOF;
  229.     }
  230.     if(--(af->_rcnt) >= 0)
  231.     {
  232.     return *(af->_ptr)++;
  233.     }
  234.     else
  235.     {
  236.     af->_ptr = af->_base;
  237.     n = s_recv(fileno(af), af->_base, af->_size, 0);
  238.     if(n > 0)
  239.     {
  240.         af->_rcnt = n-1;
  241.  
  242.         return *(af->_ptr)++;
  243.     }
  244.     else if(n == -1)
  245.     {
  246.         af->_flag |= _IOERR;
  247.         
  248.         return EOF;
  249.     }
  250.     else
  251.     {
  252.         af->_flag |= _IOEOF;
  253.  
  254.         return EOF;
  255.     }
  256.     }
  257. }
  258.  
  259. char *s_fgets(char *b, int bsize, FILE *af)
  260. {
  261.     char *p;
  262.     int c;
  263.  
  264.     if(!(af->_flag & _IOSOCK))
  265.     {
  266.     return fgets(b, bsize, af);
  267.     }
  268.     else
  269.     {
  270.     p = b;
  271.     if(!(af->_flag & _IOREAD))
  272.     {
  273.         fprintf(stderr,"s_fgets: illegal operation (read)\n");
  274.         errno = EBADF;
  275.         
  276.         return NULL;
  277.     }
  278.     while(bsize-- && ((c = _s_fgetc(af)) != EOF) && (c != '\n'))
  279.         *p++ = c; 
  280.     if(p==b)
  281.         return NULL;
  282.     if((c == EOF) && errno)
  283.         return NULL;
  284.     *p = '\0';
  285.     return b;
  286.     }
  287. }
  288.  
  289. int s_fputs(const char *b, FILE *fp)
  290. {
  291.     if(!(fp->_flag & _IOSOCK))
  292.     {
  293.     return fputs(b, fp);
  294.     }
  295.     else
  296.     {
  297.     fprintf(stderr,"s_fputs: not supported for sockets\n");
  298.     exit(20);
  299.     }
  300. }
  301.  
  302. int s_fseek(FILE *fp, long rpos, int mode)
  303. {
  304.     if(!(fp->_flag & _IOSOCK))
  305.     {
  306.     return fseek(fp, rpos, mode);
  307.     }
  308.     else
  309.     {
  310.     fprintf(stderr,"s_fseek: not supported for sockets\n");
  311.     exit(20);
  312.     }
  313. }
  314.  
  315.  
  316. int s_fgetc(FILE *af)
  317. {
  318.     if(!(af->_flag & _IOSOCK))
  319.     {
  320.     return fgetc(af);
  321.     }
  322.     else
  323.     {
  324.     if(!(af->_flag & _IOREAD))
  325.     {
  326.         fprintf(stderr,"s_fgetc: illegal operation (read)\n");
  327.         errno = EBADF;
  328.  
  329.         return EOF;
  330.     }
  331.     return _s_fgetc(af);
  332.     }
  333. }
  334.  
  335. int s_fflush(FILEEXT *af)
  336. {
  337.     int nbytes, RetVal;
  338.  
  339.     if(!(af->_flag & _IOSOCK))
  340.     {
  341.     return fflush(af);
  342.     }
  343.     else
  344.     {
  345.     if(!(af->_flag & _IOWRT))
  346.     {
  347.         fprintf(stderr,"s_fflush: illegal operation (not write)\n");
  348.         errno = EBADF;
  349.  
  350.         return EOF;
  351.     }
  352.     if(af->_wcnt)
  353.     {
  354.         nbytes = s_send(fileno(af), af->_base, af->_wcnt, 0);
  355.         if(nbytes != af->_wcnt)
  356.         {
  357.         af->_flag |= _IOERR;
  358.         RetVal = EOF;
  359.         }
  360.         else
  361.         RetVal = 0;
  362.  
  363.         af->_wcnt = 0;
  364.         af->_ptr = af->_base;
  365.     }
  366.     else
  367.         RetVal = 0;
  368.  
  369.     return RetVal;
  370.     }
  371. }
  372.  
  373. int s_vfprintf(FILE *af, const char *fmt, va_list args)
  374. {
  375.     int n;
  376.  
  377. /*     va_start(args, fmt);*/
  378.     
  379.     /* if buffer gets exceeded, we loose */
  380.  
  381.     if(!(af->_flag & _IOSOCK))
  382.     {
  383.     n = vfprintf(af, (char *) fmt, args);
  384.     }
  385.     else
  386.     {
  387.     s_fflush(af);
  388.     n = af->_wcnt = vsprintf(af->_ptr, fmt, args);
  389.     af->_ptr += n;
  390.     if(n > af->_size)
  391.     {
  392.         fprintf(stderr,"vfprintf: file buf exceeded\n");
  393.         exit(20);
  394.     }
  395.     }
  396.     va_end(args);
  397.  
  398.     return n;
  399. }
  400.  
  401. int s_fprintf(FILEEXT *af, const char *fmt, ...)
  402. {
  403.     int n;
  404.     va_list args;
  405.  
  406.     va_start(args, fmt);
  407.     
  408.     /* if buffer gets exceeded, we loose */
  409.  
  410.     if(!(af->_flag & _IOSOCK))
  411.     {
  412.     n = vfprintf(af, (char *) fmt, args);
  413.     }
  414.     else
  415.     {
  416.     s_fflush(af);
  417.     n = af->_wcnt = vsprintf(af->_ptr, fmt, (va_list) args);
  418.     af->_ptr += n;
  419.     if(n > af->_size)
  420.     {
  421.         fprintf(stderr,"fprintf: file buf exceeded\n");
  422.         exit(20);
  423.     }
  424.     }
  425.     va_end(args);
  426.  
  427.     return n;
  428. }
  429.  
  430. int s_fputc(int c, FILEEXT *af)
  431. {
  432.     int success;
  433.  
  434.     if(!(af->_flag & _IOSOCK))
  435.     {
  436.     return fputc(c, af);
  437.     }
  438.     else
  439.     {
  440.     if(!(af->_flag & _IOWRT))
  441.     {
  442.         fprintf(stderr,"s_fflush: illegal operation (write)\n");
  443.         errno = EBADF;
  444.  
  445.         return -1;
  446.     }
  447.     if(af->_wcnt > af->_size)
  448.     {
  449.         success = s_fflush(af);
  450.     }
  451.     (af->_wcnt)++;
  452.     *(af->_ptr)++ = c;
  453.  
  454.     return success ? success : c;
  455.     }
  456. }
  457.  
  458. int s_ferror(FILE *af)
  459. {
  460.     if(!(af->_flag & _IOSOCK))
  461.     {
  462.     return ferror(af);
  463.     }
  464.     else
  465.     {
  466.     return 0;        /* FIXME */
  467.     }
  468. }
  469.  
  470. int s_read(int fh, void *buf, unsigned int len)
  471. {
  472.     if(fh < MAXFH)
  473.     return read(fh, buf, len);
  474.     else
  475.     return recv(fh-MAXFH, buf, len, 0);
  476. }
  477.  
  478. int s_write(int fh, void *buf, unsigned int len)
  479. {
  480.     if(fh < MAXFH)
  481.     return write(fh, buf, len);
  482.     else
  483.     return send(fh-MAXFH, buf, len, 0);
  484. }
  485.  
  486.  
  487. int s_close(int sd)
  488. {
  489.     int RetVal;
  490.  
  491.     if(sd == 1)
  492.     {
  493.     fprintf(stderr,"s_close: someone tries to close stdout ;-(\n");
  494.     }
  495.     if(sd < MAXFH)
  496.     return close(sd);
  497.     else
  498.     {
  499. #if 0
  500.     fprintf(stderr,"s_close(%d)\n", sd -S_MAXFH);
  501. #endif
  502.     RetVal = CloseSocket(sd - MAXFH);
  503. #if 0
  504.     if(RetVal)
  505.     {
  506.         perror("s_close failed\n");
  507.     }
  508. #endif
  509.     }
  510.     return RetVal;
  511. }
  512.  
  513. int s_isatty(int sd)
  514. {
  515.     if(sd < MAXFH)
  516.     return isatty(sd);
  517.     else
  518.     {
  519.     return 0;
  520.     }
  521. }
  522.  
  523. int s_iomode(int sd, int mode)
  524. {
  525.     if(sd < MAXFH)
  526.     return isatty(sd);
  527.     else
  528.     {
  529.     return 1; /* not a level 1 file FIXME: call for sockets available? */
  530.     }
  531. }
  532.  
  533. long s_lseek(int sd, long a, int mode)
  534. {
  535.     if(sd < MAXFH)
  536.     return lseek(sd, a, mode);
  537.     else
  538.     {
  539.     fprintf(stderr,"s_lseek: not supported for sockets\n");
  540.     exit(20);
  541.     }
  542. }
  543.  
  544. long s_accept(long s, struct sockaddr *addr, int *addrlen)
  545. {
  546.     int ns;
  547.  
  548.     ns = accept(s-S_MAXFH, addr, (long *) addrlen);
  549.     if(ns>=0)
  550.     ns += S_MAXFH;
  551.     return ns;
  552. }
  553.  
  554. long s_bind(long s, struct sockaddr *name, long namelen)
  555. {
  556.     return bind(s-S_MAXFH, name, namelen);
  557. }
  558.  
  559. long s_CloseSocket(long sd)
  560. {
  561.     return CloseSocket(sd-S_MAXFH);
  562. }
  563.  
  564. long s_connect(long s, struct sockaddr *name, long namelen)
  565. {
  566.     return connect(s-S_MAXFH, name, namelen);
  567. }
  568.  
  569. long s_getpeername(long s, struct sockaddr *name, int *namelen)
  570. {
  571.     return getpeername(s-S_MAXFH, name, (long *) namelen);
  572. }
  573.  
  574. long s_getsockname(long s, struct sockaddr *name, int *namelen)
  575. {
  576.     return getsockname(s-S_MAXFH, name, (long *) namelen);
  577. }
  578.  
  579. long s_setsockopt(long s, long level, long optname, caddr_t optval, long optlen)
  580. {
  581.     return setsockopt(s-S_MAXFH, level, optname, optval, optlen);
  582.  
  583. long s_listen(long s, long backlog)
  584. {
  585.     return listen(s-S_MAXFH, backlog);
  586. }
  587.  
  588. long s_recv(long s, char *buf, long len, long flags)
  589. {
  590.     int n;
  591.  
  592.     n = recv(s-S_MAXFH, buf, len, flags);
  593. #if 0
  594.     if(n != -1)
  595.     {
  596.     fprintf(stderr,"s_recv = ");
  597.     write(2, buf, n);
  598.     fprintf(stderr,"\n");
  599.     }
  600.     else
  601.     {
  602.     fprintf(stderr,"recv returned -1\n");
  603.     }
  604. #endif
  605.     return n;
  606. }
  607.  
  608. long s_recvfrom(long s, char *buf, long len, long flags, 
  609.         struct sockaddr *from, long *len2)
  610. {
  611.     int n;
  612.  
  613.     n = recvfrom(s-S_MAXFH, buf, len, flags, from, len2);
  614.     return n;
  615. }
  616.  
  617. long s_select(long nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
  618.           struct timeval *timeout)
  619. {
  620.     return select(nfds, readfds, writefds, exceptfds, timeout);
  621. }
  622.  
  623. int s_send(int s, char *msg, int len, int flags)
  624. {
  625.     return send(s-S_MAXFH, msg, len, flags);
  626. }
  627.  
  628. int s_sendto(int s, char *msg, int len, int flags,
  629.          struct sockaddr *to, long len2)
  630. {
  631.     return sendto(s-S_MAXFH, msg, len, flags, to, len2);
  632. }
  633.  
  634. long s_shutdown(long s, long how)
  635. {
  636.     return shutdown(s-S_MAXFH, how);
  637. }
  638.  
  639. long s_socket(long domain, long type, long protocol)
  640. {
  641.     int s;
  642.     
  643.     s = socket(domain, type, protocol);
  644.     if(s>=0)
  645.     s += S_MAXFH;
  646.  
  647.     return s;
  648. }
  649.